import React from 'react'
import _ from 'lodash'
import {
  View,
  Text,
  StatusBar,
  ScrollView,
  Image,
  TouchableOpacity,
  Dimensions
} from 'react-native'

import { toJS } from 'mobx'
import { observer, useLocalObservable } from 'mobx-react-lite'
import Icon from 'react-native-vector-icons/Ionicons'
import { useNavigation } from '@react-navigation/native'
import Spinner from 'react-native-spinkit'
import { Placeholder, PlaceholderLine, Shine } from 'rn-placeholder'

import { useStores } from '../stores'
import { SearchHeader, CategoryButton, Snackbar, Gap, BookItem } from '../views'
import i18n from '../i18n'
import uuid from '../utils/uuid'
import { shortly5 } from '../utils/text'

const CardPlaceholder = observer(() => {
  const { appearance: ap } = useStores()
  return (
    <View style={{ ...styles.bookCard, backgroundColor: ap.theme.surface }}>
      <Placeholder
        Animation={Shine}
      >
        <PlaceholderLine width={30} />
        <PlaceholderLine width={60} />
        <PlaceholderLine width={90} />
      </Placeholder>
    </View>
  )
})

const TitleCard = observer(() => {
  const { appearance: ap } = useStores()
  const navigation = useNavigation()
  return (
    <View style={{ ...styles.title }}>
      <TouchableOpacity onPress={() => navigation.goBack()}>
        <Icon name='chevron-back-outline' size={33} color={ap.theme.active} />
      </TouchableOpacity>

      <View>
        <Text style={{ fontSize: 30, color: ap.theme.primary }}>{i18n.t('mall')}</Text>
      </View>

      <TouchableOpacity
        onPress={() => navigation.navigate('Search')}
        style={{ paddingLeft: 16, alignItems: 'flex-end' }}>
        <Icon name='search-outline' size={28} color={ap.theme.second} />
      </TouchableOpacity>

    </View>
  )
})

const CategoiesCard = observer(({ categories, current, onChange }) => {
  const { appearance: ap } = useStores()
  const data = _.chunk(categories, 2)
  return (
    <View style={{ ...styles.category, backgroundColor: ap.theme.background }}>
      <ScrollView horizontal={true}>
        {
          data.map(group => {
            return (
              <View>
                {
                  group.map(it => {
                    it = toJS(it)
                    if (it.index == current) {
                      return (
                        <CategoryButton
                          key={it.index}
                          title={it.name}
                          backgroundColor={ap.theme.second}
                          color={ap.theme.background} />
                      )
                    }
                    return (
                      <CategoryButton
                        key={it.index}
                        onPress={() => onChange(it.index)}
                        title={it.name}
                        backgroundColor={ap.theme.surface}
                        color={ap.theme.second} />
                    )
                  })
                }
              </View>
            )
          })
        }
      </ScrollView>
    </View>
  )
})

const CategoryBooksCard = observer(({ books, category }) => {
  const { appearance: ap, bookApi } = useStores()
  const navigation = useNavigation()
  return (
    <View style={{ ...styles.booksCard, flex: 1, backgroundColor: ap.theme.surface }}>
      <View style={{ padding: 12 }}>
        <View style={{ paddingBottom: 12 }}>
          <Text style={{ color: ap.theme.primary, fontSize: 18 }}>{category.name}</Text>
        </View>
        {
          books.length &&
          <View style={{ alignItems: 'center' }}>
            <View style={{ flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-between' }}>
              {
                books.map(it => (
                  <TouchableOpacity
                    onPress={() => navigation.push('Book', { title: it.name, _id: it._id })}
                    style={{ paddingBottom: 16, alignItems: 'center', marginRight: 3 }}
                  >
                    <Image
                      source={{ uri: bookApi.getCoverUrl(it.cover) }}
                      style={{ width: 113 * 0.63, height: 150 * 0.63, borderRadius: 6 }}
                    />
                    <Gap gap={3} />
                    <Text style={{ color: ap.theme.second, fontSize: 12 }}>{shortly5(it.name)}</Text>
                  </TouchableOpacity>
                )) ||
                <Spinner type='Circle' size={50} color={ap.theme.second} />
              }
            </View>
            <TouchableOpacity
              style={{ ...styles.largeButton, backgroundColor: ap.theme.tiny, marginBottom: 6 }}
              activeOpacity={0.6}
              onPress={() => navigation.navigate('BookList', { key: 'category', data: category })}>
              <Text style={{ color: ap.theme.second, fontSize: 14 }}>
                {i18n.t('showAll')}
              </Text>
            </TouchableOpacity>
          </View> ||
          <View style={{ alignItems: 'center' }}>
            <Spinner type='9CubeGrid' size={28} color={ap.theme.second} />
          </View>
        }
      </View>
    </View>
  )
})

const RankBooksCard = observer(() => {
  const { appearance: ap, bookApi } = useStores()
  const [books, setBooks] = React.useState()

  if (!books) {
    bookApi.fetchNewlyBooks()
      .then(data => setBooks(data.books))
      .catch(err => Snackbar.error(err.toString()))
    return <CardPlaceholder />
  }
  return (
    <View style={{ ...styles.bookCard, backgroundColor: ap.theme.surface }}>
      <View style={{ paddingBottom: 12 }}>
        <Text style={{ fontSize: 18, color: ap.theme.second }}>{i18n.t('rank')}</Text>
      </View>
      {
        books.map(book => (
          <BookItem key={book._id} needButton={false} book={book} />
        ))
      }
    </View>

  )
})

export default observer(({ navigation }) => {
  const { appearance: ap, bookApi } = useStores()

  React.useLayoutEffect(() => {
    navigation.setOptions({ title: i18n.t('mall') })
  })

  const states = useLocalObservable(() => ({
    categories: [],
    current: 0,
    currentBooks: [],
    getCurrentCategory() {
      const cur = this.categories[this.current]
      return cur || {}
    },
    setCategories(categories) {
      this.categories = categories.map((it, i) => ({ ...it, index: i }))
    },
    setCurrent(index) {
      this.current = index
      this.setCurrentBooks([])
      bookApi.fetchCategoryHotlyBooks(this.categories[index]._id, 12).then(data => {
        this.setCurrentBooks(data.books)
      }).catch(err => Snackbar.error(err.toString()))
    },
    setCurrentBooks(books) {
      this.currentBooks = books
    }
  }))

  if (!states.categories.length) {
    bookApi.fetchCategoiesList().then(data => {
      states.setCategories(data.categories)
      states.setCurrent(0)
    }).catch(err => Snackbar.error(err.toString()))
  }

  return (
    <View style={{ ...styles.container, backgroundColor: ap.theme.background }}>
      <View style={{ flex: 1 }}>
        <ScrollView stickyHeaderIndices={[1]}>
          <TitleCard />
          <CategoiesCard
            categories={states.categories}
            current={states.current}
            onChange={i => states.setCurrent(i)} />

          <View style={{ padding: 12 }}>
            {
              states.categories.length &&
              <CategoryBooksCard books={states.currentBooks}
                category={states.getCurrentCategory()} /> ||
              <></>
            }
          </View>

          <RankBooksCard />
        </ScrollView>
      </View>

    </View>
  )
})

let statusBarHeight = 0
if (Platform.OS == 'ios') {
  statusBarHeight = StatusBar.currentHeight || 45
}

const styles = {
  container: {
    flex: 1,
    paddingTop: statusBarHeight,
  },

  mainContainer: {
    flex: 1,
    marginTop: 44,
    padding: 12,
  },

  title: {
    flexDirection: 'row',
    alignItems: 'center'
  },

  category: {
    flex: 1,
    paddingLeft: 12,
    paddingRight: 12,
    paddingTop: 12,
  },

  booksCard: {
    borderRadius: 6,
  },

  largeButton: {
    borderRadius: 7,
    justifyContent: 'center',
    flexDirection: 'row',
    alignItems: 'center',
    width: Dimensions.get('window').width * 0.9,
    paddingBottom: 8,
    paddingTop: 8,
  },

  bookCard: {
    flex: 1,
    margin: 12,
    borderRadius: 6,
    padding: 12,
  },
}